winsafe\oleaut\structs/
bstr.rs

1#![allow(non_snake_case)]
2
3use crate::co;
4use crate::decl::*;
5use crate::oleaut::ffi;
6
7/// A
8/// [string data type](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr)
9/// used with COM automation.
10///
11/// Automatically calls
12/// [`SysFreeString`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysfreestring)
13/// when the object goes out of scope.
14#[repr(transparent)]
15pub struct BSTR(*mut u16);
16
17impl Drop for BSTR {
18	fn drop(&mut self) {
19		if !self.0.is_null() {
20			unsafe {
21				ffi::SysFreeString(self.0);
22			}
23		}
24	}
25}
26
27impl Default for BSTR {
28	fn default() -> Self {
29		Self(std::ptr::null_mut())
30	}
31}
32
33impl From<BSTR> for WString {
34	fn from(v: BSTR) -> WString {
35		unsafe { WString::from_wchars_nullt(v.as_ptr()) }
36	}
37}
38
39impl std::fmt::Display for BSTR {
40	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41		let txt = unsafe { WString::from_wchars_nullt(self.as_ptr()) };
42		std::fmt::Display::fmt(&txt, f)
43	}
44}
45impl std::fmt::Debug for BSTR {
46	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47		write!(f, "BSTR \"{}\"", self)
48	}
49}
50
51impl BSTR {
52	/// [`SysAllocString`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysallocstring)
53	/// function.
54	#[must_use]
55	pub fn SysAllocString(s: &str) -> HrResult<Self> {
56		let str_obj = WString::from_str(s);
57		let ptr = unsafe { ffi::SysAllocString(str_obj.as_ptr()) };
58		if ptr.is_null() { Err(co::HRESULT::E_OUTOFMEMORY) } else { Ok(Self(ptr)) }
59	}
60
61	/// [`SysReAllocString`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysreallocstring)
62	/// function.
63	///
64	/// The underlying pointer is automatically updated.
65	pub fn SysReAllocString(&mut self, s: &str) -> HrResult<()> {
66		let str_obj = WString::from_str(s);
67		let ptr = unsafe { ffi::SysReAllocString(self.0, str_obj.as_ptr()) };
68		if ptr.is_null() {
69			Err(co::HRESULT::E_OUTOFMEMORY)
70		} else {
71			self.0 = ptr;
72			Ok(())
73		}
74	}
75
76	/// [`SysStringLen`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysstringlen)
77	/// function.
78	#[must_use]
79	pub fn SysStringLen(&self) -> u32 {
80		unsafe { ffi::SysStringLen(self.0) }
81	}
82
83	/// Creates a new `BSTR` by wrapping a pointer.
84	///
85	/// # Safety
86	///
87	/// Be sure the pointer has the correct type and isn't owned by anyone else,
88	/// otherwise you may cause memory access violations.
89	#[must_use]
90	pub const unsafe fn from_ptr(p: *mut u16) -> Self {
91		Self(p)
92	}
93
94	/// Returns the underlying
95	/// [`LPWSTR`](https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings)
96	/// pointer to the null-terminated wide string.
97	#[must_use]
98	pub const fn as_ptr(&self) -> *mut u16 {
99		self.0
100	}
101
102	/// Returns a pointer to the underlying
103	/// [`LPWSTR`](https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings)
104	/// pointer to the null-terminated wide string.
105	#[must_use]
106	pub const fn as_mut_ptr(&mut self) -> *mut *mut u16 {
107		&mut self.0
108	}
109
110	/// Returns the underlying
111	/// [`LPWSTR`](https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings)
112	/// memory block as a null-terminated `u16` slice.
113	#[must_use]
114	pub fn as_slice(&self) -> &[u16] {
115		unsafe { std::slice::from_raw_parts(self.0, self.SysStringLen() as usize + 1) }
116	}
117
118	/// Ejects the underlying
119	/// [`LPWSTR`](https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings)
120	/// pointer leaving a null pointer in its place, so that
121	/// [`SysFreeString`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysfreestring)
122	/// won't be called.
123	///
124	/// Be sure to free the pointer, otherwise, as the name of this method
125	/// implies, you will cause a memory leak.
126	#[must_use]
127	pub const fn leak(&mut self) -> *mut u16 {
128		std::mem::replace(&mut self.0, std::ptr::null_mut())
129	}
130}